/*
 * StateMachine.cpp
 *
 *  Created on: Aug 29, 2013
 *      Author: jason
 */

#include "../../include/GameModes/StateMachine.hpp"
#include "../../include/GameModes/TownMode/TownMode.hpp"
namespace OForce_Mode {

StateMachine *StateMachine::m_pInstance = NULL;

StateMachine *StateMachine::Instance()
{
	if (m_pInstance == NULL) {
		m_pInstance = new StateMachine;
	}
	return m_pInstance;
}

void StateMachine::KillInstance()
{
	delete m_pInstance;
	m_pInstance = NULL;
}

StateMachine::StateMachine() : mGameState(townMode),
		nPop(0),
		changeState(false),
		isFading(false),
		mFade(false)
{
	// The initial state must be the Title State.
//	TitleMode title = new TitleMode;
//	mCurrentState = title;
	// TODO: remove this once title has been implemented
	// For testing start with the townMode
//	TownMode *town = new TownMode(_win, "test");
//	win = &Window;
	TownMode *town = new TownMode("test");
	add(town);
	mCurrentState = town;
}

StateMachine::~StateMachine() {
	mCurrentState = NULL;
	popAll();
}

void StateMachine::add(State *state) {
//	vStateStack.push_back(state);
	vPushBuffer.push_back(state);
	changeState = true;
}

// Remove state from back of the stack
void StateMachine::pop() {
//	if (!vStateStack.empty()) {
//		delete vStateStack.back();
//		vStateStack.pop_back();
//		mCurrentState = vStateStack.back();
//	}
	nPop++;
	changeState = true;
}

void StateMachine::popAll() {
//	while (!vStateStack.empty()) {
//		if (vStateStack.back() != NULL)
//			delete vStateStack.back();
//		vStateStack.pop_back();
//	}
	nPop = vStateStack.size();
}

void StateMachine::update()
{
	if (changeState) {
		if (isFading) {
			fadeTimer -= dt;
			if (fadeTimer <= 0.0) {
				isFading = false;
				fadeTimer = 0.0f;
			}
			fadeRect.setFillColor(sf::Color(0,0,0,255*fadeTimer/0.75f));
		} else {
			while (nPop > 0) {
				if (vStateStack.empty()) {
					std::cout << "Warning: attempted to pop from an empty stack.\n";
					nPop = 0;
					break;
				}
				delete vStateStack.back();
				vStateStack.pop_back();
				nPop--;
			}
			while (!vPushBuffer.empty()) {
				// Pause the previous buffer
				// TODO Implement this in State
				//		if (!vStateStack.empty() && vStateStack.back()) {
				//			vStateStack.back()->pauseState();
				//		}
				vStateStack.push_back(vPushBuffer.back());
				vPushBuffer.pop_back();
			}
			if (vStateStack.empty()) {
				Window.close();
			}
			// TODO
			//		vStateStack.back()->restart();
			mFade = false;
			changeState = false;
		}
	} else {
		if (vStateStack.back()) {
			vStateStack.back()->update();
		}
	}
}

void StateMachine::draw()
{
	vStateStack.back()->draw();
	if (mFade) {
		Window.draw(fadeRect);
	}
}

void StateMachine::startFading()
{
	sf::Vector2f viewCenter = view.getCenter();
	sf::Vector2f viewSize = view.getSize();
	fadeRect.setPosition(viewCenter.x-viewSize.x, viewCenter.y-viewSize.y);
	viewSize.x *= 2;
	viewSize.y *= 2;
	fadeRect.setSize(viewSize);
	fadeRect.setFillColor(sf::Color(0,0,0,255));
	fadeTimer = 0.75f;
	isFading = true;
	mFade = true;
}

}


